package org.jflame.context.filemanager;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.jflame.commons.model.Chars;
import org.jflame.commons.net.HttpHelper;
import org.jflame.commons.util.MapHelper;
import org.jflame.commons.util.StringHelper;

/**
 * 对象存储基类
 * 
 * @author charles.zhang
 */
public abstract class OssFileManager<T extends OssManagerCfg> extends RemoteFileManager<T> {

    protected String copy_name_fmt = "_copy_%s_%s";

    public OssFileManager(T clientCfg) {
        super(clientCfg);
        StringHelper.requireNonEmpty(clientCfg.getAccessId(), "no accessId configured");
        StringHelper.requireNonEmpty(clientCfg.getAccessSecret(), "no accessSecret configured");
        StringHelper.requireNonEmpty(clientCfg.getBucket(), "no bucket configured");
    }

    @SuppressWarnings("unchecked")
    public OssFileManager(String ossEndpoint, String ossAccessId, String ossAccessSecret, String currentBucket) {
        this((T) new OssManagerCfg(ossEndpoint, ossAccessId, ossAccessSecret, currentBucket));
    }

    /**
     * 生成预签名文件上传(put方式)地址,供第三方上传文件
     * 
     * @param saveDir 文件保存文件夹
     * @param fileNameOrExt 文件名或扩展名(扩展名以.开头)
     * @param expireTime 预签名过期时间，单位秒. 空或0使用默认过期时间
     * @return
     */
    public SignedUrl generatePresignedPutUrl(String saveDir, String fileNameOrExt, Integer expireTime) {
        return generatePresignedPutUrl(new PresignedUrlArgs(saveDir, fileNameOrExt, expireTime));
    }

    /**
     * 生成预签名文件上传(put方式)地址,供第三方上传文件
     * 
     * @param args 预签名url参数
     * @return
     */
    public abstract SignedUrl generatePresignedPutUrl(PresignedUrlArgs args);

    /**
     * 生成预签名文件下载(get方式)地址,供第三方获取文件
     * 
     * @param args 预签名url参数
     * @return
     */
    public abstract String generatePresignedGetUrl(PresignedUrlArgs args);

    /**
     * 生成终端直传文件(post方式)用的参数
     * 
     * @param args 预签名url参数
     * @return
     */
    public abstract Map<String,String> generatePostObjectParams(PresignedUrlArgs args);

    public abstract void createBucket(String bucketName);

    protected Map<String,String> setContentType(String fileId, Map<String,String> headers) {
        if (MapHelper.isEmpty(headers) || !headers.containsKey(HttpHelper.HEADER_CONTENTTYPE)) {
            Optional<String> mimeType = guessContentType(fileId);
            if (mimeType.isPresent()) {
                if (headers == null) {
                    headers = new HashMap<>();
                }
                headers.put(HttpHelper.HEADER_CONTENTTYPE, mimeType.get());
            }
        }
        return headers;
    }

    /**
     * 根据判断文件全名判断是不是目录,一般oss以路径/划分模拟目录逻辑结构,/结尾表示是一个目录
     * 
     * @param fileid
     * @return
     */
    protected boolean isDir(String fileid) {
        return fileid.length() > 1 && StringHelper.endChar(fileid) == Chars.SLASH;
    }

    /**
     * 列举文件时筛选出符合条件的文件名,只列举当前目录文件,不迭代子目录
     * 
     * @param filename
     * @param isExcludeDir
     * @param filenames
     */
    protected void filterFilename(String filename, int dirLen, Boolean isExcludeDir, List<String> filenames) {
        int separatorIndex = filename.indexOf(Chars.SLASH, dirLen);
        // 子目录文件忽略
        if (separatorIndex > 0) {
            // 保留直接目录
            if (!(isExcludeDir && separatorIndex == filename.length() - 1)) {
                return;
            }
        }
        filenames.add(filename);
    }

    public String getCurrentBucket() {
        return getConfig().getBucket();
    }

}
